home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 25 / CU Amiga Magazine's Super CD-ROM 25 (1998)(EMAP Images)(GB)(Track 1 of 2)[!][issue 1998-08].iso / CUCD / Programming / BlitzList / BlitzListFiles / blitzbotz.lha / BlitzBotz.asc next >
Encoding:
Text File  |  1998-05-11  |  12.0 KB  |  471 lines

  1. ;Blitz Botz
  2.  
  3. WBStartup:DEFTYPE.w
  4.  
  5. #BOT_MAX=3                ;number of bots
  6. #CYCLE_MAX=1000           ;number of calls each bot gets
  7. #GRID_HEIGHT=17           ;height of grid must be odd, and over 2
  8. #GRID_WIDTH=31            ;width of grid must be odd, and over 2
  9. #GRID_COMPLEX=8           ;30 is least, 1 is most complex
  10. #GRID_EMPTY=5             ;how empty is the grid??
  11.  
  12. #GRID_SIZE=#GRID_WIDTH*#GRID_HEIGHT
  13. #TABLE_LIMIT=(#GRID_WIDTH/2)*(#GRID_HEIGHT/2)
  14.  
  15. NEWTYPE .botstats
  16.   xpos.w:ypos:dir:bottype
  17.   shotx.w:shoty:shotdir
  18.   time.l:shots
  19.   moved.w
  20. End NEWTYPE
  21.  
  22. Dim List stats.botstats(0)
  23. Dim GRID.w(0,0)
  24. Dim hits(0,0)
  25.  
  26. Function.w BOT_FIRE{}
  27.   SHARED stats.botstats()
  28.   USEPATH stats()
  29.   If \shotx=-1
  30.     \shotdir=\dir:\shotx=\xpos:\shoty=\ypos:\shots=\shots+1
  31.     Function Return True
  32.   Else
  33.     Function Return False
  34.   EndIf
  35. End Function
  36.  
  37. Function.w BOT_FORWARD{}
  38.   SHARED GRID(),stats.botstats()
  39.   USEPATH stats()
  40. ;  Locate 0,0:Print "X=",\xpos," Y=",\ypos,"      "
  41.   If \moved=0
  42.     newx.w=\xpos:newy.w=\ypos
  43.     Select \dir
  44.       Case 0:newy=newy-1
  45.       Case 1:newx=newx+1
  46.       Case 2:newy=newy+1
  47.       Case 3:newx=newx-1
  48.     End Select
  49.     If GRID(newx,newy)<16
  50.       \moved=1:GRID(\xpos,\ypos)=GRID(\xpos,\ypos)&$FDF:GRID(newx,newy)=GRID(newx,newy)|32
  51.       \xpos=newx:\ypos=newy
  52.       Function Return True
  53.     Else
  54.       Function Return False
  55.     EndIf
  56.   Else
  57.     Function Return False
  58.   EndIf
  59. End Function
  60.  
  61. Function.w BOT_TURNCW{}
  62.   ;returns what you can see in the square ahead (that you've just turned too - clockwise)
  63.   SHARED GRID.w(),stats.botstats()
  64.   USEPATH stats()
  65.   \dir=\dir+1:If \dir=4 Then \dir=0
  66.   Select \dir
  67.     Case 0:tmp=GRID(\xpos,\ypos-1)
  68.     Case 1:tmp=GRID(\xpos+1,\ypos)
  69.     Case 2:tmp=GRID(\xpos,\ypos+1)
  70.     Case 3:tmp=GRID(\xpos-1,\ypos)
  71.   End Select
  72.   Function Return tmp
  73. End Function
  74.  
  75. Function.w BOT_TURNAC{}
  76.   ;returns what you can see in the square ahead (that you've just turned too - anti clockwise)
  77.   SHARED GRID.w(),stats.botstats()
  78.   USEPATH stats()
  79.   \dir=\dir-1:If \dir=-1 Then \dir=3
  80.   Select \dir
  81.     Case 0:tmp=GRID(\xpos,\ypos-1)
  82.     Case 1:tmp=GRID(\xpos+1,\ypos)
  83.     Case 2:tmp=GRID(\xpos,\ypos+1)
  84.     Case 3:tmp=GRID(\xpos-1,\ypos)
  85.   End Select
  86.   Function Return tmp
  87. End Function
  88.  
  89. Function.w BOT_LOOK{squares.w}
  90.   SHARED GRID.w(),stats.botstats()
  91.   USEPATH stats()
  92.   ;look squares ahead of the bot
  93.   newx=\xpos:newy=\ypos:tmp=-1
  94.   Select \dir
  95.     Case 0:newy=newy-squares
  96.     Case 1:newx=newx+squares
  97.     Case 2:newy=newy+squares
  98.     Case 3:newx=newx-squares
  99.   End Select
  100.   If (newx>-1)&(newx<#GRID_WIDTH)
  101.     If (newy>-1)&(newy<#GRID_HEIGHT)
  102.       tmp=GRID(newx,newy)
  103.     EndIf
  104.   EndIf
  105.   Function Return tmp
  106. End Function
  107.  
  108. Statement UPDATE_SHOTS{}
  109.   SHARED GRID(),hits(),stats.botstats()
  110.   ResetList stats():USEPATH stats()
  111.   While NextItem(stats())
  112.     If \shotx<>-1
  113.       newx=\shotx:newy=\shoty:GRID(newx,newy)=GRID(newx,newy)&$FFE
  114.       Select GRID(newx,newy)&$FF0
  115.         Case 32   ;hit bot...find bot then kill shot
  116.           If (\xpos<>newx)|(\ypos<>newy)
  117.             PushItem stats():shothit=0:ResetList stats()
  118.             While (NextItem(stats()))&(shothit=0)
  119.               If (\xpos=newx)&(\ypos=newy) Then shothit=\bottype
  120.             Wend
  121.             PopItem stats()
  122.             hits(\bottype,shothit)=hits(\bottype,shothit)+1:newx=-1
  123.           EndIf
  124.         Case 256:newx=-1
  125.       End Select
  126.       If newx<>-1
  127.         Select \shotdir
  128.           Case 0:newy=newy-1
  129.           Case 1:newx=newx+1
  130.           Case 2:newy=newy+1
  131.           Case 3:newx=newx-1
  132.         End Select
  133.         Select GRID(newx,newy)&$FF0
  134.           Case 32   ;hit bot...find bot then kill shot
  135.             If (\xpos<>newx)|(\ypos<>newy)
  136.               PushItem stats():shothit=0:ResetList stats()
  137.               While (NextItem(stats()))&(shothit=0)
  138.                 If (\xpos=newx)&(\ypos=newy) Then shothit=\bottype
  139.               Wend
  140.               PopItem stats()
  141.               hits(\bottype,shothit)=hits(\bottype,shothit)+1:newx=-1
  142.             EndIf
  143.           Case 256:newx=-1
  144.         End Select
  145.       EndIf
  146.       \shotx=newx:\shoty=newy
  147.     EndIf
  148.   Wend
  149.   ;now draw them all into the grid
  150.   ResetList stats()
  151.   While NextItem(stats())
  152.     If \shotx<>-1 Then GRID(\shotx,\shoty)=GRID(\shotx,\shoty)|1
  153.   Wend
  154. End Statement
  155.  
  156. Statement Gerbil{}
  157.   If Rnd(100)>69
  158.     If BOT_TURNAC{}<>0
  159.       nil=BOT_TURNAC{}
  160.       If BOT_TURNAC{}<>0
  161.         If BOT_TURNAC{}=0 Then nil=BOT_FORWARD{} Else nil=BOT_TURNAC{}
  162.       EndIf
  163.     EndIf
  164.   EndIf
  165.   nil=BOT_FORWARD{}
  166.   If Rnd(100)>49
  167.     nil=BOT_TURNCW{}:nil=BOT_TURNCW{}
  168.     nil=BOT_FIRE{}
  169.     nil=BOT_TURNAC{}:nil=BOT_TURNAC{}
  170.   EndIf
  171. End Statement
  172.  
  173. Statement Gophor{}
  174.   If Peek.l(?Gophor_Flag)=0
  175.     If (Rnd(100)>69)|(BOT_FORWARD{}=False)
  176.       If BOT_TURNAC{}<>0
  177.         nil=BOT_TURNAC{}
  178.         If BOT_TURNAC{}<>0
  179.           If BOT_TURNAC{}<>0 Then nil=BOT_TURNAC{}
  180.         EndIf
  181.       EndIf
  182.     EndIf
  183.     tmp=0
  184.     While (BOT_TURNAC{}&32=0)&(tmp<3)
  185.       tmp+1
  186.     Wend
  187.     If (tmp<3)|(BOT_LOOK{1}&32=32) Then Poke.l ?Gophor_Flag,1  ;we've found bot, so stick with it
  188.   Else
  189.     nil=BOT_FORWARD{}
  190.     If BOT_LOOK{1}&32=0
  191.       tmp=0
  192.       While (BOT_TURNAC{}&32=0)&(tmp<3)
  193.         tmp+1
  194.       Wend
  195.       If tmp=3 Then Poke.l ?Gophor_Flag,0     ;go back to random searching if somehow lost bot
  196.     EndIf
  197.     nil=BOT_FIRE{}
  198.   EndIf
  199.   Goto Gophor_Skip
  200. Gophor_Flag:  Dc.l  0
  201. Gophor_Skip:
  202. End Statement
  203.  
  204. Statement Hamster{}
  205.   If BOT_FORWARD{}=False
  206.     If Rnd(3)>0 Then nil=BOT_TURNAC{} Else nil=BOT_TURNCW{}
  207.   Else
  208.     nil=BOT_FIRE{}
  209.   EndIf
  210. End Statement
  211.  
  212. If NTSC Then vsize.w=60 Else vsize.w=50
  213.  
  214. Gosub INIT_DISPLAY
  215.  
  216. Gosub MAKE_GRID:Gosub INIT_BOTS
  217.  
  218. ResetTimer:cycles.l=0
  219.  
  220. Repeat
  221.   ResetList stats():USEPATH stats()
  222.   While NextItem(stats())
  223.     \moved=0:timestart.l=Ticks
  224.  
  225.     Select \bottype             ;add your bots here
  226.       Case 1:Gerbil{}
  227.       Case 2:Gophor{}
  228.       Case 3:Hamster{}
  229.     End Select
  230.  
  231.     timenew.l+(Ticks-timestart):\time=\time+timenew
  232.   Wend
  233.   UPDATE_SHOTS{} ;:VWait
  234.   Gosub SHOW_GRID
  235.   cycles+1
  236. Until cycles=#CYCLE_MAX
  237.  
  238. Gosub SHOW_STATS
  239.  
  240. MouseWait
  241.  
  242. End
  243.  
  244. INIT_BOTS:
  245.   ;randomize startup positions, and order
  246.   Dim List stats.botstats(#BOT_MAX-1)
  247.   Dim hits(#BOT_MAX,#BOT_MAX)
  248.   Dim order(#BOT_MAX-1)
  249.   For loop=1 To #BOT_MAX:order(loop-1)=loop:Next loop
  250.   For loop=1 To 100
  251.     Exchange order(Rnd(#BOT_MAX)),order(Rnd(#BOT_MAX))
  252.   Next loop
  253.   ClearList stats():USEPATH stats()
  254.   For loop=1 To #BOT_MAX
  255.     If AddItem(stats())
  256.       \bottype=order(loop-1):\dir=Rnd(4):\time=0:\moved=0:\shotx=-1:\shoty=0:\shotdir=0
  257.       posokay=False
  258.       While posokay=False
  259.         \xpos=Rnd(#GRID_WIDTH):\ypos=Rnd(#GRID_HEIGHT)
  260.         If GRID(\xpos,\ypos)=0 Then posokay=True:GRID(\xpos,\ypos)=32
  261.       Wend
  262.     EndIf
  263.   Next loop
  264. Return
  265.  
  266. MAKE_GRID:
  267.   ;generate the grid
  268.   Dim GRID.w(#GRID_WIDTH-1,#GRID_HEIGHT-1)
  269.   Dim TABLE(#TABLE_LIMIT-1,1)
  270.   For xloop=0 To #GRID_WIDTH-1
  271.     For yloop=0 To #GRID_HEIGHT-1
  272.       If (xloop&1)AND(yloop&1) Then GRID(xloop,yloop)=0 Else GRID(xloop,yloop)=1
  273.     Next yloop
  274.   Next xloop
  275.   Gosub MAKE_PATH
  276.   tablemax=0
  277.   For xloop=0 To #GRID_WIDTH-1
  278.     For yloop=0 To #GRID_HEIGHT-1
  279.       If (xloop&1)AND(yloop&1)
  280.         If GRID(xloop,yloop)=2 Then TABLE(tablemax,0)=xloop:TABLE(tablemax,1)=yloop:tablemax+1
  281.       End If
  282.     Next yloop
  283.   Next xloop
  284.   ;now jumble all used positions (COMPLEX NUMBER OF TIMES)
  285.   For loop=0 To #GRID_COMPLEX
  286.     For loop1=0 To tablemax-1
  287.       newpos=Rnd(tablemax):Exchange TABLE(loop1,0),TABLE(newpos,0)
  288.       Exchange TABLE(loop1,1),TABLE(newpos,1)
  289.     Next loop1
  290.   Next loop
  291.   For loop=0 To #TABLE_LIMIT-1
  292.     xpos=TABLE(loop,0):ypos.l=TABLE(loop,1)
  293.     trydirection=0:moved=0:length=0
  294.     While moved=0
  295.       If length>=#GRID_COMPLEX-1 Then direction=Rnd(4):length=0
  296.       newxpos=xpos:newypos=ypos:wallxpos=xpos:wallypos=ypos
  297.       Select direction
  298.         Case 0:newxpos-2:wallxpos-1:trydirection|1
  299.         Case 1:newypos-2:wallypos-1:trydirection|2
  300.         Case 2:newxpos+2:wallxpos+1:trydirection|4
  301.         Case 3:newypos+2:wallypos+1:trydirection|8
  302.       End Select
  303.       If (newxpos>0)AND(newxpos<#GRID_WIDTH)
  304.         If (newypos>0)AND(newypos<#GRID_HEIGHT)
  305.           If (GRID(wallxpos,wallypos)=1)AND(GRID(newxpos,newypos)=0)
  306.             GRID(wallxpos,wallypos)=0:GRID(xpos,ypos)=2
  307.             TABLE(tablemax,0)=newxpos:TABLE(tablemax,1)=newypos:tablemax+1
  308.             xpos=newxpos:ypos=newypos:trydirection=0:length+1
  309.           Else
  310.             If trydirection=15
  311.               GRID(xpos,ypos)=2:moved=1
  312.             Else
  313.               direction=Rnd(4)
  314.             End If
  315.           End If
  316.         Else
  317.           direction=Rnd(4)
  318.         End If
  319.       Else
  320.         direction=Rnd(4)
  321.       End If
  322.     Wend
  323.   Next loop
  324.   ;now cleanup grid (we only want 0 + 256 in grid)
  325.   For xloop=0 To #GRID_WIDTH-1
  326.     For yloop=0 To #GRID_HEIGHT-1
  327.       Select GRID(xloop,yloop)
  328.         Case 1:GRID(xloop,yloop)=256
  329.         Default:GRID(xloop,yloop)=0
  330.       End Select
  331.       If Rnd(100)<#GRID_EMPTY
  332.         If (yloop>0)&(yloop<(#GRID_HEIGHT-1))
  333.           If (xloop>0)&(xloop<(#GRID_WIDTH-1)) Then GRID(xloop,yloop)=0
  334.         EndIf
  335.       EndIf
  336.     Next yloop
  337.   Next xloop
  338. Return
  339.  
  340. SHOW_GRID:
  341.   ;display it on currently used bitmap
  342.   showscale=8:showcircle=showscale/2 ;:Cls 0
  343.   For xloop=0 To #GRID_WIDTH-1
  344.     xpos=xloop*showscale
  345.     For yloop=0 To #GRID_HEIGHT-1
  346.       ypos=yloop*showscale
  347.       Select GRID(xloop,yloop)
  348.         Case 1:Boxf xpos,ypos,xpos+showscale-1,ypos+showscale-1,0:Boxf xpos+1,ypos+1,xpos+showscale-2,ypos+showscale-2,3
  349.         Case 32:Circlef xpos+showcircle-1,ypos+showcircle-1,showcircle,showcircle,2
  350.         Case 256:Boxf xpos,ypos,xpos+showscale-1,ypos+showscale-1,1
  351.         Default:Boxf xpos,ypos,xpos+showscale-1,ypos+showscale-1,0
  352.       End Select
  353.     Next yloop
  354.   Next xloop
  355. ;  now show bot colours
  356. ;  ResetList stats():USEPATH stats()
  357. ;  While NextItem(stats())
  358. ;  Wend
  359. Return
  360.  
  361. SHOW_STATS:
  362.   ResetList stats():USEPATH stats()
  363.   Locate 0,0:ply=0:Format "00000"
  364.   NPrint "Ply     Bot     Shots   Hit     TimePerCycle"
  365.   While NextItem(stats())
  366.     mytype=\bottype:hitnum.l=0
  367.     For loop=1 To #BOT_MAX
  368.       hitnum=hitnum+hits(mytype,loop)
  369.     Next loop
  370.     NPrint ply,"   ",\bottype,"   ",\shots,"   ",hitnum,"   ",\time/#CYCLE_MAX
  371.     ply+1
  372.   Wend
  373.   NPrint ""
  374.   NPrint " Cycles = ",#CYCLE_MAX
  375. Return
  376.  
  377. INIT_DISPLAY:
  378.   Screen 0,12,"BlitzBotz V0.1 Test!"
  379.   ScreensBitMap 0,0:BitMapOutput 0
  380. Return
  381.  
  382. MAKE_PATH:
  383.   ;makes a single random path through the grid
  384.   xpos=Rnd(((#GRID_WIDTH-1)/2)*2)|1
  385.   ypos=Rnd(((#GRID_HEIGHT-1)/2)*2)|1
  386.   For loop=0 To #GRID_COMPLEX
  387.     length=0:path=0:trydirection=0:direction=Rnd(4)
  388.     While (length<#GRID_COMPLEX)AND(path=0)
  389.       Select direction
  390.         Case 0:Gosub GO_LEFT:trydirection|1
  391.         Case 1:Gosub GO_UP:trydirection|2
  392.         Case 2:Gosub GO_RIGHT:trydirection|4
  393.         Case 3:Gosub GO_DOWN:trydirection|8
  394.       End Select
  395.       If GRID(xpos,ypos)=0
  396.         direction=Rnd(4):If trydirection=15 Then path=1
  397.       Else
  398.         length+1
  399.         Select direction
  400.           Case 0:xpos-2
  401.           Case 1:ypos-2
  402.           Case 2:xpos+2
  403.           Case 3:ypos+2
  404.         End Select
  405.         trydirection=0
  406.         If xpos<1 Then path=1:xpos+2
  407.         If xpos>=#GRID_WIDTH Then path=1:xpos-2
  408.         If ypos<1 Then path=1:ypos+2
  409.         If YPOS>=#GRID_HEIGHT Then path=1:ypos-2
  410.       End If
  411.     Wend
  412.   Next loop
  413.   GRID(xpos,ypos)=2
  414. Return
  415.  
  416. GO_LEFT:
  417.   If (xpos-2)>0
  418.     If GRID(xpos-2,ypos)<>2
  419.       GRID(xpos-1,ypos)=0
  420.       GRID(xpos,ypos)=2
  421.     End If
  422.   End If
  423. Return
  424.  
  425. GO_RIGHT:
  426.   If (xpos+2)<#GRID_WIDTH
  427.     If GRID(xpos+2,ypos)<>2
  428.       GRID(xpos+1,ypos)=0
  429.       GRID(xpos,ypos)=2
  430.     End If
  431.   End If
  432. Return
  433.  
  434. GO_UP:
  435.   If (ypos-2)>0
  436.     If GRID(xpos,ypos-2)<>2
  437.       GRID(xpos,ypos-1)=0
  438.       GRID(xpos,ypos)=2
  439.     End If
  440.   End If
  441. Return
  442.  
  443. GO_DOWN:
  444.   If (ypos+2)<#GRID_HEIGHT
  445.     If GRID(xpos,ypos+2)<>2
  446.       GRID(xpos,ypos+1)=0
  447.       GRID(xpos,ypos)=2
  448.     End If
  449.   End If
  450. Return
  451.  
  452. ;GRID
  453. ;
  454. ; -1  - outside of grid
  455. ;                           you can move through this group
  456. ; 0   - empty square
  457. ; 1   - shot
  458. ; 2   -
  459. ; 4   -
  460. ;                           you can't move through this group (reserved for players-bots etc)
  461. ; 16  -
  462. ; 32  - bot
  463. ; 64  -
  464. ; 128 -
  465. ;                           A solid block (impassable stuff.....)
  466. ; 256 - block
  467. ;
  468.  
  469.  
  470.  
  471.